package com.alibaba.service;

import com.alibaba.common.ResponseResult;
import com.alibaba.common.SystemConstants;
import com.alibaba.define.domain.ArticleDO;
import com.alibaba.define.domain.CategoryDO;
import com.alibaba.define.domain.vo.ArticleDetailVO;
import com.alibaba.define.domain.vo.ArticleListVO;
import com.alibaba.define.domain.vo.HotArticleVO;
import com.alibaba.define.domain.vo.PageVO;
import com.alibaba.manager.ArticleManager;
import com.alibaba.mapper.ArticleMapper;
import com.alibaba.define.service.ArticleService;
import com.alibaba.mapper.CategoryMapper;
import com.alibaba.utils.BeanCopyUtils;
import com.alibaba.utils.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.alibaba.define.enums.AppHttpCodeEnum.*;

/**
 * @author : hanyang
 * @date : 2023-10-29 13:02
 **/

@Slf4j
@Service
public class ArticleServiceImpl implements ArticleService {

    @Resource
    ArticleMapper articleDAO;

    @Resource
    ArticleManager articleManager;

    @Resource
    CategoryMapper categoryDAO;

    @Resource
    RedisCache redisCache;


    @Override
    public ResponseResult<List<HotArticleVO>> hotArticleList() {
        try {
            List<ArticleDO> articleDOS = articleDAO.hotArticleList();
            List<HotArticleVO> hotArticleVOS = BeanCopyUtils.copyBeanList(articleDOS, HotArticleVO.class);
            return ResponseResult.ok(hotArticleVOS);
        } catch (Exception e) {
            log.error("[ArticleService] query hotArticleList error!", e);
        }
        return ResponseResult.error(SYSTEM_EXECUTE_ERROR.getCode(), SYSTEM_EXECUTE_ERROR.getMsg());
    }

    @Override
    public ResponseResult<PageVO> articleList(Integer pageNum, Integer pageSize, Long categoryId) {
        PageVO pageVO = new PageVO();
        try {
            // 参数校验
            if (Objects.isNull(pageNum) || Objects.isNull(pageSize) || pageNum < 1 || pageSize < 0) {
                return ResponseResult.error(WRONG_PARAMETER.getCode(), WRONG_PARAMETER.getMsg());
            }
            // categoryId的处理
            if (categoryId < 1) {
                categoryId = null;
            }
            List<ArticleDO> articleDOS = articleManager.getEfficientArticleByPagination(pageNum, pageSize, categoryId);
            if (CollectionUtils.isEmpty(articleDOS)) {
                return ResponseResult.error(QUERY_RESULT_NULL.getCode(), QUERY_RESULT_NULL.getMsg());
            }
            // 查询redis中的浏览量
            Map<String, Integer> viewCountMap = redisCache.getCacheMap(SystemConstants.ARTICLE_VIEW_COUNT_KEY);
            // DO => VO
            List<ArticleListVO> articleListVOS = articleDOS.stream().map(articleDO -> {
                ArticleListVO articleListVO = BeanCopyUtils.copyBean(articleDO, ArticleListVO.class);
                CategoryDO categoryDO = categoryDAO.selectById(articleDO.getCategoryId());
                articleListVO.setCategoryName(categoryDO.getName());
                Integer viewCount = viewCountMap.get(articleDO.getId().toString());
                articleListVO.setViewCount(viewCount.longValue());
                return articleListVO;
            }).collect(Collectors.toList());

            pageVO.setRows(articleListVOS);
            pageVO.setTotal(articleManager.queryArticleCountByCondition(categoryId));
            return ResponseResult.ok(pageVO);
        } catch (Exception e) {
            log.error("[ArticleService] query articleList error! request:pageNum:{} | pageSize:{} | categoryId:{}", pageNum, pageSize, categoryId, e);
        }
        return ResponseResult.error(SYSTEM_EXECUTE_ERROR.getCode(), SYSTEM_EXECUTE_ERROR.getMsg());
    }

    @Override
    public ResponseResult<ArticleDetailVO> getArticleDetailById(Long id) {
        try {
            // 参数校验
            if (Objects.isNull(id)) {
                return ResponseResult.error(WRONG_PARAMETER.getCode(), WRONG_PARAMETER.getMsg());
            }
            ArticleDO articleDO = articleManager.queryArticleById(id);
            // 查询结果校验
            if (Objects.isNull(articleDO)) {
                return ResponseResult.error(QUERY_RESULT_NULL.getCode(), QUERY_RESULT_NULL.getMsg());
            }
            // DO => VO
            ArticleDetailVO articleDetailVO = BeanCopyUtils.copyBean(articleDO, ArticleDetailVO.class);
            CategoryDO categoryDO = categoryDAO.selectById(articleDetailVO.getCategoryId());
            articleDetailVO.setCategoryName(categoryDO.getName());
            // 从redis中查询文章的浏览量
            Map<String, Integer> viewCountMap = redisCache.getCacheMap(SystemConstants.ARTICLE_VIEW_COUNT_KEY);
            Integer redisViewCount = viewCountMap.get(articleDO.getId().toString());
            articleDetailVO.setViewCount(redisViewCount.longValue());
            return ResponseResult.ok(articleDetailVO);
        } catch (Exception e) {
            log.error("[ArticleService] query articleList error! request: id:{}", id);
        }
        return ResponseResult.error(SYSTEM_EXECUTE_ERROR.getCode(), SYSTEM_EXECUTE_ERROR.getMsg());
    }

    @Override
    public ResponseResult<Void> updateArticleViewCount(Long id) {
        // 更新Redis里的viewCount
        log.info("start updateArticleViewCount to Redis! articleId:{}", id);
        redisCache.incrementCacheMapValue(SystemConstants.ARTICLE_VIEW_COUNT_KEY, id.toString(), 1);
        log.info("updateArticleViewCount success!");
        return null;
    }
}

